flag_verbose: bool,
flag_manifest_path: Option<String>,
flag_no_verify: bool,
+ flag_no_metadata: bool,
flag_list: bool,
}
-h, --help Print this message
-l, --list Print files included in a package without making one
--no-verify Don't verify the contents by building them
+ --no-metadata Ignore warnings about a lack of human-usable metadata
--manifest-path PATH Path to the manifest to compile
-v, --verbose Use verbose output
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
ops::package(&root, shell,
!options.flag_no_verify,
- options.flag_list).map(|_| None).map_err(|err| {
+ options.flag_list,
+ !options.flag_no_metadata).map(|_| None).map_err(|err| {
CliError::from_boxed(err, 101)
})
}
pub fn package(manifest_path: &Path,
shell: &mut MultiShell,
verify: bool,
- list: bool) -> CargoResult<Option<Path>> {
+ list: bool,
+ metadata: bool) -> CargoResult<Option<Path>> {
let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
try!(src.update());
let pkg = try!(src.get_root_package());
+ if metadata {
+ try!(check_metadata(&pkg, shell));
+ }
+
if list {
let root = pkg.get_manifest_path().dir_path();
let mut list: Vec<_> = try!(src.list_files(&pkg)).iter().map(|file| {
Ok(Some(bomb.path.take().unwrap()))
}
+// check that the package has some piece of metadata that a human can
+// use to tell what the package is about.
+fn check_metadata(pkg: &Package, shell: &mut MultiShell) -> CargoResult<()> {
+ let md = pkg.get_manifest().get_metadata();
+
+ let mut missing = vec![];
+
+ macro_rules! lacking {
+ ($($field: ident),*) => {{
+ $(
+ if md.$field.as_ref().map_or(true, |s| s.is_empty()) {
+ missing.push(stringify!($field))
+ }
+ )*
+ }}
+ }
+ lacking!(description, license)
+
+ if !missing.is_empty() {
+ let mut things = missing.slice_to(missing.len() - 1).connect(", ");
+ // things will be empty if and only if length == 1 (i.e. the only case to have no `or`).
+ if !things.is_empty() {
+ things.push_str(" or ");
+ }
+ things.push_str(*missing.last().unwrap());
+
+ try!(shell.warn(
+ format!("Warning: manifest has no {things}. \
+ See http://doc.crates.io/manifest.html#package-metadata for more info.",
+ things = things).as_slice()))
+ }
+ Ok(())
+}
+
fn tar(pkg: &Package, src: &PathSource, shell: &mut MultiShell,
dst: &Path) -> CargoResult<()> {
let (mut registry, reg_id) = try!(registry(shell, token, index));
try!(verify_dependencies(&pkg, ®_id));
- // Prepare a tarball
- let tarball = try!(ops::package(manifest_path, shell, verify, false)).unwrap();
+ // Prepare a tarball, with a non-surpressable warning if metadata
+ // is missing since this is being put online.
+ let tarball = try!(ops::package(manifest_path, shell, verify, false, true)).unwrap();
// Upload said tarball to the specified destination
try!(shell.status("Uploading", pkg.get_package_id().to_string()));
license = "..."
```
+The [crates.io](https://crates.io) registry will render the description, display
+the license, link to the three URLs and categorize by the keywords. These keys
+provide useful information to users of the registry and also influence the
+search ranking of a crate. It is highly discouraged to omit everything in a
+published crate.
+
# The `[dependencies.*]` Sections
pub static DOWNLOADING: &'static str = " Downloading";
pub static UPLOADING: &'static str = " Uploading";
pub static VERIFYING: &'static str = " Verifying";
+pub static WARNING: &'static str = " Warning";
use flate2::reader::GzDecoder;
use support::{project, execs, cargo_dir, ResultTest};
-use support::{PACKAGING, VERIFYING, COMPILING};
+use support::{PACKAGING, WARNING, VERIFYING, COMPILING};
use hamcrest::{assert_that, existing_file};
fn setup() {
version = "0.0.1"
authors = []
exclude = ["*.txt"]
+ license = "MIT"
+ description = "foo"
"#)
.file("src/main.rs", r#"
fn main() { println!("hello"); }
"unexpected filename: {}", f.filename())
}
})
+
+test!(metadata_warning {
+ let p = project("all")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+ assert_that(p.cargo_process("package"),
+ execs().with_status(0).with_stdout(format!("\
+{packaging} foo v0.0.1 ({dir})
+{verifying} foo v0.0.1 ({dir})
+{compiling} foo v0.0.1 ({dir}[..])
+",
+ packaging = PACKAGING,
+ verifying = VERIFYING,
+ compiling = COMPILING,
+ dir = p.url()).as_slice())
+ .with_stderr("Warning: manifest has no description or license. See \
+ http://doc.crates.io/manifest.html#package-metadata for more info."));
+
+ let p = project("one")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ "#)
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+ assert_that(p.cargo_process("package"),
+ execs().with_status(0).with_stdout(format!("\
+{packaging} foo v0.0.1 ({dir})
+{verifying} foo v0.0.1 ({dir})
+{compiling} foo v0.0.1 ({dir}[..])
+",
+ packaging = PACKAGING,
+ verifying = VERIFYING,
+ compiling = COMPILING,
+ dir = p.url()).as_slice())
+ .with_stderr("Warning: manifest has no description. See \
+ http://doc.crates.io/manifest.html#package-metadata for more info."));
+
+ let p = project("both")
+ .file("Cargo.toml", format!(r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+ "#))
+ .file("src/main.rs", r#"
+ fn main() {}
+ "#);
+ assert_that(p.cargo_process("package"),
+ execs().with_status(0).with_stdout(format!("\
+{packaging} foo v0.0.1 ({dir})
+{verifying} foo v0.0.1 ({dir})
+{compiling} foo v0.0.1 ({dir}[..])
+",
+ packaging = PACKAGING,
+ verifying = VERIFYING,
+ compiling = COMPILING,
+ dir = p.url()).as_slice()));
+
+})
name = "foo"
version = "0.0.1"
authors = []
+ license = "MIT"
+ description = "foo"
"#)
.file("src/main.rs", "fn main() {}");
name = "foo"
version = "0.0.1"
authors = []
+ license = "MIT"
+ description = "foo"
[dependencies.foo]
git = "git://path/to/nowhere"
name = "foo"
version = "0.0.1"
authors = []
+ license = "MIT"
+ description = "foo"
[dependencies.bar]
path = "bar"
name = "foo"
version = "0.0.1"
authors = []
+ license = "MIT"
+ description = "foo"
[dependencies.notyet]
version = "0.0.1"